/*
 * @Author: 吴世扬 18368095041@163.com
 * @Date: 2025-02-14 12:04:27
 * @LastEditors: 吴世扬 18368095041@163.com
 * @LastEditTime: 2025-02-26 08:48:15
 * @FilePath: /vue3-admin-server/src/common/filters/CatchEverythingFilter.ts
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import {
    ExceptionFilter,
    Catch,
    ArgumentsHost,
    HttpException,
    HttpStatus
} from '@nestjs/common';
import { HttpAdapterHost } from '@nestjs/core';

import { Logger } from 'winston'; // 添加: 引入 Winston 的 Logger
import { Inject } from '@nestjs/common'; // 添加: 引入 Inject 装饰器
import { generateObjFromError, errorRes } from 'src/common/utils';

@Catch()
export class CatchEverythingFilter implements ExceptionFilter {
    constructor(
        private readonly httpAdapterHost: HttpAdapterHost,
        @Inject('winston')
        private readonly logger: Logger
    ) {}

    catch(exception: unknown, host: ArgumentsHost): void {
        const { httpAdapter } = this.httpAdapterHost;

        const ctx = host.switchToHttp();
        const request: HwRequest = ctx.getRequest();

        const httpStatus =
            exception instanceof HttpException
                ? exception.getStatus()
                : HttpStatus.INTERNAL_SERVER_ERROR;

        let data: Record<string, unknown> = {};
        let error = '';
        if (exception instanceof Error) {
            data = generateObjFromError(exception);
            error = JSON.stringify(data);
        } else {
            data.info = exception;
            error = String(exception);
        }

        this.logger.error({
            date: Date(),
            error,
            request: {
                method: request.method,
                url: request.url,
                headers: request.headers,
                body: request.body as unknown
            }
        });

        httpAdapter.reply(
            ctx.getResponse(),
            errorRes(undefined, data),
            httpStatus
        );
    }
}
